﻿using System;
using System.Drawing;

using Storm.TextEditor.Win32;
using Storm.TextEditor.Win32.Enums;
using Storm.TextEditor.Win32.Structs;

namespace Storm.TextEditor.Core
{
    public class IMEWindow
    {
        #region Fields

        private const int IMC_SETCOMPOSITIONWINDOW = 0x000c;
        private const int CFS_POINT = 0x0002;
        private const int IMC_SETCOMPOSITIONFONT = 0x000a;

        private const byte FF_MODERN = 48;
        private const byte FIXED_PITCH = 1;

        private IntPtr hIMEWnd = IntPtr.Zero;
        private Font font = null;
        private Point location = new Point(0, 0);

        #endregion

        #region Properties

        public Font Font
        {
            get { return font; }
            set
            {
                if (font.Equals(value) == false)
                {
                    SetFont(value);
                    font = value;
                }
            }
        }

        public Point Location
        {
            get { return location; }
            set
            {
                location = value;

                POINTAPI p = new POINTAPI();
                p.X = value.X;
                p.Y = value.Y;

                COMPOSITIONFORM lParam = new COMPOSITIONFORM();
                lParam.dwStyle = CFS_POINT;
                lParam.ptCurrentPos = p;
                lParam.rcArea = new RECTAPI();

                NativeUser32Api.SendMessage(
                    hIMEWnd,
                    (int)WindowMessage.WM_IME_CONTROL,
                    IMC_SETCOMPOSITIONWINDOW,
                    lParam);
            }
        }

        #endregion

        #region Methods

        #region Public

        public void SetFont(Font font)
        {
            LogFont lf = new LogFont();
            font.ToLogFont(lf);
            lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;

            NativeUser32Api.SendMessage(
                hIMEWnd, (int)WindowMessage.WM_IME_CONTROL,
                IMC_SETCOMPOSITIONFONT,
                lf);
        }

        public void SetFont(string fontname, float fontsize)
        {
            LogFont tFont = new LogFont();
            tFont.lfItalic = (byte)0;
            tFont.lfStrikeOut = (byte)0;
            tFont.lfUnderline = (byte)0;
            tFont.lfWeight = 400;
            tFont.lfWidth = 0;
            tFont.lfHeight = (int)(-fontsize * 1.3333333333333);
            tFont.lfCharSet = 1;
            tFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
            tFont.lfFaceName = fontname;

            LogFont lf = tFont;

            NativeUser32Api.SendMessage(
                hIMEWnd, (int)WindowMessage.WM_IME_CONTROL,
                IMC_SETCOMPOSITIONFONT,
                lf);
        }

        #endregion

        #endregion

        /// <summary>
        /// Initializes a new instance of IMEWindow.
        /// </summary>
        public IMEWindow(IntPtr hWnd, string fontname, float fontsize)
        {
            hIMEWnd = NativeImm32Api.ImmGetDefaultIMEWnd(hWnd);
            SetFont(fontname, fontsize);
        }
    }
}
